package com.jade.linkong.service.impl;

import com.jade.common.constant.Constants;
import com.jade.common.core.text.Convert;
import com.jade.common.utils.DateUtils;
import com.jade.common.utils.StringUtils;
import com.jade.framework.util.ShiroUtils;
import com.jade.linkong.domain.LkMatterAlarmLog;
import com.jade.linkong.domain.LkMatterProject;
import com.jade.linkong.domain.LkNotice;
import com.jade.linkong.domain.LkProject;
import com.jade.linkong.mapper.LkNoticeMapper;
import com.jade.linkong.service.ILkMatterAlarmLogService;
import com.jade.linkong.service.ILkMatterProjectService;
import com.jade.linkong.service.ILkNoticeService;
import com.jade.linkong.service.ILkProjectService;
import com.jade.system.domain.SysNotice;
import com.jade.system.domain.SysUser;
import com.jade.system.service.ISysNoticeService;
import com.jade.tool.generator.service.impl.GenTableServiceImpl;
import com.jade.tool.generator.util.VelocityInitializer;
import com.jade.tool.generator.util.VelocityUtils;
import org.apache.commons.io.IOUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import oshi.jna.platform.mac.SystemB;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 告示Service业务层处理
 * 
 * @author jade
 * @date 2020-07-16
 */
@Service
public class LkNoticeServiceImpl implements ILkNoticeService
{
    private static final Logger log = LoggerFactory.getLogger(GenTableServiceImpl.class);

    @Autowired
    private LkNoticeMapper lkNoticeMapper;

    @Autowired
    private ISysNoticeService sysNoticeService;

    @Autowired
    private ILkMatterProjectService matterProjectService;

    @Autowired
    private ILkProjectService projectService;

    @Autowired
    private ILkMatterAlarmLogService matterAlarmLogService;

    /**
     * 查询告示
     * 
     * @param lkNoticeId 告示ID
     * @return 告示
     */
    @Override
    public LkNotice selectLkNoticeById(Long lkNoticeId)
    {
        return lkNoticeMapper.selectLkNoticeById(lkNoticeId);
    }

    /**
     * 查询告示列表
     * 
     * @param lkNotice 告示
     * @return 告示
     */
    @Override
    public List<LkNotice> selectLkNoticeList(LkNotice lkNotice)
    {
        String roleKey = ShiroUtils.getSysUser().getRoleKey();
        if ( StringUtils.isNotNull(roleKey) && roleKey.equals("company")){
            LkMatterProject matterProject = new LkMatterProject();
            matterProject.setMainOrg(ShiroUtils.getSysUser().getUserId().toString());
            lkNotice.setLkMatterProject(matterProject);
        }else if (StringUtils.isNotNull(roleKey) && roleKey.equals("dept")){
            LkMatterProject matterProject = new LkMatterProject();
            matterProject.setMainOrg(ShiroUtils.getSysUser().getDeptId().toString());
            lkNotice.setLkMatterProject(matterProject);
        }

        return lkNoticeMapper.selectLkNoticeList(lkNotice);
    }

    /**
     * 新增告示
     * 
     * @param lkNotice 告示
     * @return 结果
     */
    @Override
    public int insertLkNotice(LkNotice lkNotice)
    {
        lkNotice.setCreateTime(DateUtils.getNowDate());
        return lkNoticeMapper.insertLkNotice(lkNotice);
    }

    /**
     * 修改告示
     * 
     * @param lkNotice 告示
     * @return 结果
     */
    @Override
    public int updateLkNotice(LkNotice lkNotice)
    {
        lkNotice.setUpdateTime(DateUtils.getNowDate());
        return lkNoticeMapper.updateLkNotice(lkNotice);
    }

    /**
     * 删除告示对象
     * 
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteLkNoticeByIds(String ids)
    {
        String[] noticeIds = Convert.toStrArray(ids);
        for (String nId : noticeIds){
            LkNotice lkNotice = lkNoticeMapper.selectLkNoticeById(Long.parseLong(nId));
            updateMatterLightStatus(lkNotice);
        }
        return lkNoticeMapper.deleteLkNoticeByIds(noticeIds);
    }

    /**
     * 删除告示信息
     * 
     * @param lkNoticeId 告示ID
     * @return 结果
     */
    public int deleteLkNoticeById(Long lkNoticeId)
    {
        LkNotice lkNotice = lkNoticeMapper.selectLkNoticeById(lkNoticeId);
        updateMatterLightStatus(lkNotice);
        return lkNoticeMapper.deleteLkNoticeById(lkNoticeId);
    }

    /**
     * 修改关联告示单的事项亮灯类型
     * @param lkNotice
     */
    private void updateMatterLightStatus(LkNotice lkNotice){
        LkMatterProject matterProject = new LkMatterProject();
        matterProject.setId(lkNotice.getLkMatterProjectId());
        matterProject.setProjectId(Long.parseLong(lkNotice.getLkProjectId()));
        matterProject.setLight("0");
        matterProjectService.updateLightStatus(matterProject);

    }

    @Override
    public void addNotice(LkMatterProject lkMatterProject) {
        // 根据项目id与警告类型判断是否重复生成告示单
        LkNotice notice = new LkNotice();
        notice.setLkMatterProjectId(lkMatterProject.getId());
        notice.setLkProjectId(lkMatterProject.getProjectId().toString());
        notice.setLightType(lkMatterProject.getLight());
        notice.setDelFlag("0");
        List<LkNotice> lkNotices = lkNoticeMapper.selectLkNoticeList(notice);
        if (lkNotices != null && lkNotices.size() == 0){
            // 添加告示单
            notice.setType(lkMatterProject.getOrgStatus().replaceAll(" ", ""));
            notice.setLkProCode(lkMatterProject.getId().toString()); // 项目编号
            notice.setName(lkMatterProject.getName());
            notice.setContent(lkMatterProject.getMatterContent());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            notice.setPlanningTime(sdf.format(lkMatterProject.getExpectedDate()));
            notice.setCreateTime(new Date());
            notice.setIsRead("2");

            // 修改事项状态
            LkMatterProject matterProject = new LkMatterProject();
            matterProject.setId(lkMatterProject.getId());
            matterProject.setProjectId(lkMatterProject.getProjectId());
            matterProject.setLight(lkMatterProject.getLight());

            //修改项目状态
            LkProject lkProject = new LkProject();
            lkProject.setProId(lkMatterProject.getProjectId());


            // 添加通知
            SysNotice sysNotice = new SysNotice();
            sysNotice.setNoticeTitle("1".equals(lkMatterProject.getLight()) ?
                   "事项\"" + lkMatterProject.getName() + "\"事项红色警告" :  "事项\"" +lkMatterProject.getName() + "\"事项黄色警告" );
            sysNotice.setNoticeContent("1".equals(lkMatterProject.getLight()) ?
                    lkMatterProject.getName() + "，事项已进入红色警告。" : lkMatterProject.getName() + "，事项已进入黄色警告。" );
            sysNotice.setNoticeType("1");
            sysNotice.setStatus("0");

            lkNoticeMapper.insertLkNotice(notice);
            matterProjectService.updateLkMatterProject(matterProject);
            LkProject lkProject1 = projectService.selectLkProjectById(lkMatterProject.getProjectId().toString());
            // 如果项目已经是红灯状态就不修改警告状态
            if (lkProject1 != null && !"1".equals(lkProject1.getLightStatus()) ){
                lkProject.setLightStatus(lkMatterProject.getLight());
                projectService.updateLkProject(lkProject);
            }
            sysNoticeService.insertNotice(sysNotice);

            // 添加警报记录
            LkMatterAlarmLog matterAlarmLog = new LkMatterAlarmLog(
                    Long.valueOf(lkProject1.getProId()),
                    lkProject1.getProName(),
                    lkMatterProject.getId(),
                    lkMatterProject.getName(),
                    Integer.parseInt(lkMatterProject.getLight()),
                    new Date()
                    );
//            matterAlarmLog.setMainOrgId(Integer.parseInt(lkMatterProject.getMainOrg()));
//            matterAlarmLog.setMainOrgName(lkMatterProject.getMainOrgname());
            matterAlarmLogService.insertLkMatterAlarmLog(matterAlarmLog);
//            LkNotice lkNotice = lkNotices.get(0);
//            if (lkMatterProject.getLight().equals("1")){
//                sysNoticeService.insertNotice(sysNotice);
//            }else{
//                sysNoticeService.updateNotice(sysNotice);
//            }

        };
 
    }

    @Override
    public String previewNotice(Long id) {
        // 查询表信息
        LkNotice notice = lkNoticeMapper.selectLkNoticeById(id);
        return getTemplate(notice);
    }

    @Override
    public String previewNotice(LkNotice lkNotice) {
        LkNotice notice = lkNoticeMapper.selectLkNoticeByProjectIdAndMatterProjectId(lkNotice);
        return getTemplate(notice);
    }

    @Override
    public byte[] exportNotice(Long id) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ZipOutputStream zip = new ZipOutputStream(outputStream);
        generatorCode(id, zip);
        IOUtils.closeQuietly(zip);
        return outputStream.toByteArray();
    }

    @Override
    public byte[] exportNotice(String[] ids) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ZipOutputStream zip = new ZipOutputStream(outputStream);
        for (String id : ids){
            generatorCode(Long.parseLong(id), zip);
        }
        IOUtils.closeQuietly(zip);
        return outputStream.toByteArray();
    }


    private void generatorCode(Long id, ZipOutputStream zip)
    {

        // 查询表信息
        LkNotice notice = lkNoticeMapper.selectLkNoticeById(id);
        VelocityInitializer.initVelocity();
        VelocityContext context = VelocityUtils.prepareContext(notice);

        // 模板渲染
        String template = VelocityUtils.getTemplateNotice(notice);
//        String template = "vm/doc/companyRed.doc.vm";
        StringWriter sw = new StringWriter();
        Template tpl = Velocity.getTemplate(template, Constants.UTF8);
        tpl.merge(context, sw);

        try
        {
            // 添加到zip
            zip.putNextEntry(new ZipEntry(  notice.getLkProCode()+ notice.getName().replace("/", "")+"_告示单.doc"));
            IOUtils.write(sw.toString(), zip, Constants.UTF8);
            IOUtils.closeQuietly(sw);
            zip.closeEntry();
        }
        catch (IOException e)
        {
            log.error("渲染模板失败，事项名：" + notice.getName(), e);
        }

    }

    private String getTemplate(LkNotice notice){
        VelocityInitializer.initVelocity();
        VelocityContext context = VelocityUtils.prepareContext(notice);

        // 判断登录用户是否属于责任部门并修改属性为已读
        SysUser user = ShiroUtils.getSysUser();
        String roleKey = ShiroUtils.getSysUser().getRoleKey();
        String principalId = ""; // 负责人id
        if ( StringUtils.isNotNull(roleKey) && roleKey.equals("company")){
            principalId = user.getUserId().toString();
        }else{
            principalId = user.getDeptId().toString();
        }
        if (notice.getLkMatterProject().getMainOrg().equals(principalId)){
            LkNotice notice1 = new LkNotice();
            notice1.setLkNoticeId(notice.getLkNoticeId());
            notice1.setIsRead("1");
            notice1.setSignatureUserId(user.getUserId());
            notice1.setSignatureUserName(user.getUserName());
            notice1.setSignatureTime(new Date());
            lkNoticeMapper.updateLkNotice(notice1);
        }

        // 模板渲染
        String template = VelocityUtils.getTemplateNotice(notice);
        StringWriter sw = new StringWriter();
        Template tpl = Velocity.getTemplate(template, Constants.UTF8);
        tpl.merge(context, sw);

        return sw.toString();
    }
}
